﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Drawing;
using BattleThis.Core;
using System.IO;
using System.Text.RegularExpressions;
using System.IO.Compression;
using System.Text;
using BattleThis.Helpers;
using BattleThis.Mvc;

namespace BattleThis.Controllers
{

	/// <summary>
	/// Controller provides Svg-Files.
	/// </summary>
    public class SvgController : InGameControllerAbstract
    {

		#region Variablen

		/// <summary>
		/// Key to the cache in the application-state.
		/// </summary>
		public const string CacheKey = "SvgFileCache";

		/// <summary>
		/// Name of the RenderUnit aciton.
		/// </summary>
		public const string RenderUnit = "RenderUnit";

		public static readonly ReflectedControllerDescriptor Info = new ReflectedControllerDescriptor( typeof( SvgController ) );
		#endregion

		#region Properties

		/// <summary>
		/// Gets the cache of the file that exists.
		/// </summary>
		public List	<string> Cache
		{ 
			get
			{
				if( !this.ExistAppDataCache() ) 
						this.CreateAppDataCache();

				return (List<string>)this.HttpContext.Application[ CacheKey ];
			}
		}

		#endregion

		#region Methoden
		[ActionName( RenderUnit )]
		public ActionResult Render( int unitId )
		{

			if( !ExistAppDataCache() )
			{
				CreateAppDataCache();
			}

			Player player = this.Game.Players.Where( x => x.HasUnit( unitId ) ).Single();
			Color playerColor = player.Color;
			Unit unit =  player.Army.Where( x => x.Id.Equals( unitId ) ).Single();

			string file = GetFile( playerColor, unit );

			Response.AppendHeader( "Content-Encoding", "gzip" );

			return File( file, SvgColorTemplateResult.MimeType );

		}

		/// <summary>
		/// Gets the full-file-path to to the color file.
		/// </summary>
		/// <param name="playerColor">Color of the player.</param>
		/// <param name="unit">The unit.</param>
		/// <returns></returns>
		private string GetFile( Color playerColor, Unit unit )
		{
			if( unit == null )throw new ArgumentNullException( "unit" );

			string filePattern = this.CreateFilePattern( playerColor, unit );

			if( !this.Cache.Any( x => x.EndsWith( filePattern ) ))
			{
				this.AddToCache( playerColor, unit );
			}

			return this.Cache.Where( x => x.EndsWith(filePattern) ).Single() ;
		}

		/// <summary>
		/// Adds to cache a file that is requested.
		/// </summary>
		/// <param name="playerColor">Color of the player.</param>
		/// <param name="unit">The unit to render.</param>
		private void AddToCache(  Color playerColor, Unit unit )
		{
			if( unit == null )throw new ArgumentNullException( "unit" );

			var templateFile = string.Format( "~/Design/{0}.svg", unit.Type.ToString() );
			var filePath = this.HttpContext.ApplicationInstance.GetLocalPath( templateFile );
			var tempDataPath =  this.HttpContext.ApplicationInstance.GetLocalAppDataPath();
			var template = new SvgColorTemplate( filePath );
			var result = template.Dyed( playerColor );

			result.FileName =  this.CreateFilePattern( playerColor, unit ); ;
			var saveResult = result.SaveAsGzip( tempDataPath );

			this.Cache.Add( saveResult.FullName );
		}

		/// <summary>
		/// Creates the file pattern.
		/// </summary>
		/// <param name="playerColor">Color of the player.</param>
		/// <param name="unit">The unit.</param>
		/// <returns></returns>
		private  string CreateFilePattern( Color playerColor, Unit unit )
		{
			if( unit == null )throw new ArgumentNullException( "unit" );

			return string.Concat( unit.Type.ToString(), playerColor.ToHex(), SvgColorTemplateResult.ZippedFileExtension );
		}

		/// <summary>
		/// Check if the app data cache exists.
		/// </summary>
		/// <returns>True if Exist, false even not.</returns>
		private bool ExistAppDataCache()
		{
			return this.HttpContext.Application[ CacheKey ] != null;
		}

		/// <summary>
		/// Creates the app data cache.
		/// </summary>
		private void CreateAppDataCache()
		{
			this.HttpContext.Application[ CacheKey ] = new List<string>();

			var appdataFolder = this.HttpContext.ApplicationInstance.GetLocalAppDataPath();
			var existing = Directory.GetFiles( appdataFolder, SvgColorTemplateResult.SearchPatternsSvgz );

			this.Cache.AddRange( existing );
		}

		#endregion

    }
}
